package com.yangchuang.openpicture.service;

import com.aliyun.oss.model.ObjectMetadata;
import com.yangchuang.openpicture.constant.FileUploadConstants;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;

/**
 * 阿里云OSS对象存储服务接口 (适配公共读Bucket模式)
 * <p>
 * 该接口设计用于操作设置为“公共读”权限的OSS存储桶。
 * 文件上传、删除等写操作仍需授权，而文件访问则通过拼接生成永久公开URL。
 * </p>
 */
public interface OSSService {

    // --- 文件上传 ---

    /**
     * 上传单个文件到阿里云OSS。
     *
     * @param file     待上传的文件
     * @param fileType 文件类型枚举，用于确定存储目录 (如: images/, avatars/)
     * @return 返回文件在OSS中唯一的对象名称 (Object Name)，例如："images/uuid.jpg"。此名称是后续操作此文件的句柄。
     */
    String uploadFile(MultipartFile file, FileUploadConstants fileType);

    /**
     * 批量上传文件到阿里云OSS。
     *
     * @param files    待上传的文件列表
     * @param fileType 文件类型枚举，用于确定所有文件的存储目录
     * @return 返回所有成功上传文件的 Object Name 列表。
     */
    List<String> uploadFiles(List<MultipartFile> files, FileUploadConstants fileType);


    // --- 文件删除 (依然需要授权，逻辑不变) ---

    /**
     * 【推荐】根据文件的Object Name从阿里云OSS删除单个文件。
     *
     * @param objectName 待删除文件的唯一对象名称
     */
    void deleteFileByObjectName(String objectName);

    /**
     * 【兼容】根据文件的完整URL从阿里云OSS删除单个文件。
     *
     * @param fileUrl 待删除文件的完整公开URL
     */
    void deleteFileByUrl(String fileUrl);

    /**
     * 【推荐】根据文件的Object Name列表从阿里云OSS批量删除文件。
     *
     * @param objectNames 待删除文件的唯一对象名称列表
     */
    void deleteFilesByObjectNames(List<String> objectNames);


    // --- 公开链接获取 (核心变更) ---

    /**
     * 【核心变更】根据Object Name获取文件的公开访问链接。
     * <p>
     * <b>注意：</b>由于Bucket为公共读，此方法不再生成有时效的“签名URL”，
     * 而是直接返回一个永久性的、公开的访问链接。
     * </p>
     *
     * @param objectName          需要获取访问链接的文件的Object Name
     * @return 永久性的、公开可访问的文件URL。
     */
    String getSignedUrlByObjectName(String objectName);

    /**
     * 【核心变更】根据文件的完整URL获取其标准的公开访问链接。
     * <p>
     * 主要用于URL的规范化。即使传入的URL已能访问，此方法也能确保返回基于当前系统配置的标准URL。
     * </p>
     *
     * @param fileUrl             需要获取访问链接的文件的完整URL
     * @param expirationInMinutes <b>[此参数在公共读模式下被忽略]</b>
     * @return 永久性的、公开可访问的文件URL。
     */
    String getSignedUrlByUrl(String fileUrl, long expirationInMinutes);


    // --- 实用工具方法 ---

    /**
     * 根据Object Name拼接出文件的不带签名的完整URL。
     * <p>
     * 这是公共读模式下获取文件链接的核心辅助方法。
     * </p>
     * @param objectName 文件的Object Name
     * @return 文件的完整公开URL
     */
    String getFullUrlByObjectName(String objectName);

    /**
     * 根据Object Name获取文件在OSS中的元数据。
     * <p>
     * 元数据包含文件大小(Content-Length)、文件类型(Content-Type)等重要信息。
     * </p>
     * @param objectName 文件的Object Name
     * @return 文件的元数据对象，获取失败时可能返回null或抛出异常。
     */
    ObjectMetadata getObjectMetadata(String objectName);
}